/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package sourceryobjects;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import sourcery.GraphicsContext;

/**
 *
 * @author claire
 */
public class SceneGraph implements Serializable {

    private static final int REPEL2=2500;
    private List<sNode> nodes;
    private List<sRelation> relations;
    private List<sRelationType> relationtypes;

    public SceneGraph() {
        relationtypes = new ArrayList<sRelationType>();
        nodes = new ArrayList<sNode>();
        relations = new ArrayList<sRelation>();
    }
    
    public sRelationType getRelationType(int index) {
        return relationtypes.get(index);
    }
    public int countRelationTypes() {
        return relationtypes.size();
    }
    public void addRelationType(sRelationType type){
        relationtypes.add(type);
    }

    public void update() {
        ListIterator<sRelation> r = relations.listIterator();
        while(r.hasNext()) {
            sRelation rel = r.next();
            rel.update();
        }

        ListIterator<sNode> i = nodes.listIterator();
        while (i.hasNext()) {
            sNode a = i.next();

            ListIterator<sNode> j = nodes.listIterator(i.nextIndex());
            while (j.hasNext()) {
                sNode b = j.next();
                sPoint d = a.getCoords().minus(b.getCoords());
                double dxy = d.length2();
                if(dxy < REPEL2) {
                    
                    sPoint pull = d.scale((REPEL2-dxy)/REPEL2);
                    a.pull(pull);
                    b.pull(pull.opposite());
                }
            }
        }
        i = nodes.listIterator();
        while (i.hasNext()) {
            sNode a = i.next();
           a.update();
        }
    }

    public void draw(GraphicsContext gc) {
        Iterator<sRelation> j = relations.iterator();
        while (j.hasNext()) {
            sRelation d = j.next();
            d.draw(gc);
        }
        Iterator<sNode> i = nodes.iterator();
        while (i.hasNext()) {
            sNode d = i.next();
            d.draw(gc);
        }
    }

    public void add(sNode p) {
        nodes.add(p);
    }

    public void addRelation(sNode a, sNode b, sRelationType type){
        relations.add(new sRelation(a, b, type));
    }

    public void addRelation(sRelation a){
        relations.add(a);
    }

    public boolean removeRelation(sNode rel){
        boolean found=false;
        Iterator<sRelation> i = relations.iterator();
        while(i.hasNext()) {
            sRelation a = i.next();
            if(a.getA() == rel || a.getB() == rel) {
                i.remove();
                found=true;
            }
        }
        return found;
    }
    public boolean removeRelation(sRelation rel){
        boolean found=false;
        Iterator<sRelation> i = relations.iterator();
        while(i.hasNext()) {
            sRelation a = i.next();
            if(a == rel) {
                i.remove();
                found=true;
            }
        }
        return found;
    }

    public sNode collide(sPoint mouselocation) {
        sNode found = null;
        Iterator<sNode> i = nodes.iterator();
        while (i.hasNext() && found == null) {
            sNode d = i.next();
            found = d.collide(mouselocation);
        }
        return found;
    }
    public void listStyles() {
        Iterator<sRelationType> i = relationtypes.iterator();
        while (i.hasNext()) {
            sRelationType d = i.next();
            System.out.println(d);
        }

    }
}
